package org.clockworkmages.games.anno1186.text;

import java.util.LinkedHashMap;
import java.util.Map.Entry;

import org.clockworkmages.games.anno1186.GameBeansContext;
import org.clockworkmages.games.anno1186.scripting.ScriptingService;

class ConditionalTextNode implements TextNode {

	private LinkedHashMap<String, ComplexTextNode> conditionalChildren = new LinkedHashMap<String, ComplexTextNode>();

	private ComplexTextNode defaultChild;

	// private String ifExpression;

	public ConditionalTextNode(String ifExpression) {

		String remainingText = ifExpression;
		int ifCount = 0;
		int lengthSoFar = 0;
		int startOfCurrentCondition = 0;
		while (true) {
			remainingText = ifExpression.substring(lengthSoFar);
			int firstIfIndex = remainingText.indexOf("${if ");
			int firstFiIndex = remainingText.indexOf("${fi}");
			int firstElseIndex = remainingText.indexOf("${else");

			if (firstIfIndex > -1 && firstIfIndex < firstFiIndex
					&& (firstIfIndex < firstElseIndex || firstElseIndex == -1)) {
				// "${fi}" is the first placeholder in the remaining text
				ifCount++;
				if (ifCount == 1) {
					startOfCurrentCondition = lengthSoFar + firstIfIndex;
				}
				// else {
				// ignore, it's an embedded lower-level "if" condition that will
				// be parsed later
				// }
			} else if (firstElseIndex > -1 && firstElseIndex < firstFiIndex
					&& (firstElseIndex < firstIfIndex || firstIfIndex == -1)) {
				// "${else}" or {$elseif} is the first placeholder in the
				// remaining text
				if (ifCount == 1) {
					String conditionalPiece = ifExpression.substring(
							startOfCurrentCondition, lengthSoFar
									+ firstElseIndex);
					registerConditionalChild(conditionalPiece);
					startOfCurrentCondition = lengthSoFar + firstElseIndex;
				}
				// else {
				// ignore, it's an embedded lower-level "if" condition that will
				// be parsed later
				// }
			} else if (firstFiIndex == -1) {
				throw new RuntimeException(
						"Conditional expression is invalid and cannot be parsed!");
			} else {
				// "${fi}" is the first placeholder in the remaining text
				if (ifCount == 1) {
					String conditionalPiece = ifExpression
							.substring(startOfCurrentCondition, lengthSoFar
									+ firstFiIndex);
					registerConditionalChild(conditionalPiece);
					break;
				} else {
					ifCount--;
				}
			}
			lengthSoFar += remainingText.indexOf("}") + 1;
		}

	}

	private void registerConditionalChild(String conditionPiece) {
		int beginningOfCondition = conditionPiece.indexOf(" ");
		int endOfCondition = conditionPiece.indexOf("}");
		String text = conditionPiece.substring(endOfCondition + 1);
		ComplexTextNode textNode = new ComplexTextNode(text);

		if (beginningOfCondition == -1 || beginningOfCondition > endOfCondition) {
			// "${else}" condition:
			defaultChild = textNode;
		} else {
			// "${if ...}" or "${elseif ...}" condition:
			String condition = conditionPiece.substring(
					beginningOfCondition + 1, endOfCondition);
			this.conditionalChildren.put(condition, textNode);
		}
	}

	@Override
	public String getParsedText() {
		for (Entry<String, ComplexTextNode> entry : conditionalChildren
				.entrySet()) {
			if (GameBeansContext.getBean(ScriptingService.class)
					.conditionIsMet(entry.getKey())) {
				return entry.getValue().getParsedText();
			}
		}
		if (defaultChild != null) {
			return defaultChild.getParsedText();
		}
		return "";
		// sb.append("[ELSE {" + defaultChild.getParsedText() + "}]");
		// return sb.toString();
	}

}